import 'package:flutter/material.dart';

typedef SwipeBannerCallBack = Function(int page);

class SwipeBanner extends StatefulWidget {
  final double height;
  final double paddingTopBottom;
  final double paddingLeftRight;
  final double cardRadius;
  final List<String> srcs;

  const SwipeBanner(
    this.srcs, {
    Key key,
    this.height = 115,
    this.paddingTopBottom = 15,
    this.paddingLeftRight = 15,
    this.cardRadius = 8,
  })  : assert(srcs != null),
        assert(srcs.length > 0),
        super(key: key);

  @override
  _SwipeBannerState createState() => _SwipeBannerState();
}

class _SwipeBannerState extends State<SwipeBanner> {
  PageController _pageController = PageController();
  int _currentPage = 0;
  double _pointOffset = 0;
  double _lastPointOffset = 0;

  _buildIndicatorItem(
      {double itemHeight, bool isCurrent, bool isOffset, bool expansion}) {
    BoxDecoration boxDecoration = BoxDecoration(
        borderRadius: BorderRadius.circular(10), color: Colors.white);
    double nextCurrentWidth = (1 - _pointOffset) * itemHeight + itemHeight;
    double preCurrentWidth = (_pointOffset) * itemHeight + itemHeight;

    double width = 0;
    if (isOffset) {
      if (expansion) {
        width = preCurrentWidth;
      } else {
        width = nextCurrentWidth;
      }
    } else {
      if (isCurrent) {
        width = itemHeight * 2;
      } else {
        width = itemHeight;
      }
    }

    return Container(
      decoration: boxDecoration,
      margin: EdgeInsets.only(left: 5),
      width: width,
      height: itemHeight,
    );
  }

  ///创建指示器
  List<Widget> _buildIndicator(int length, int currentIndex) {
    List<Widget> list = List();
    double itemHeight = 7.0;
    bool isNext = _pointOffset > _lastPointOffset;
    for (int i = 0; i < length; i++) {
      list.add(_buildIndicatorItem(
        itemHeight: itemHeight,
        isCurrent: i == currentIndex,
        isOffset: _pointOffset > 0,
        expansion: isNext,
      ));
    }
    _lastPointOffset = _pointOffset;
    return list;
  }

  _resetCurrentIndex(int currentInde) {
    setState(() {
      _currentPage = currentInde;
    });
  }

//  重置页面状态
  _resetPageState(int length) {
    setState(() {
      _currentPage = length;
      _pageController.jumpToPage(_currentPage);
    });
  }

  @override
  void initState() {
    super.initState();
    _pageController.addListener(() {
      setState(() {
        _pointOffset = _pageController.offset /
            (context.size.width - 2 * widget.paddingLeftRight) %
            1;
        print('[indicator]_pointOffset:$_pointOffset');
      });
    });
  }

  ///生成滑动的banner容器
  _buildSwipeBannerContainer(
      {double height = 115,
      double cardRadius = 8,
      double paddingTopBottom = 15,
      double paddingLeftRight = 15,
      SwipeBannerCallBack callBack}) {
    var length = widget.srcs.length;
    return Container(
      height: widget.height + 2 * widget.paddingTopBottom,
      padding: EdgeInsets.only(
          left: widget.paddingLeftRight, right: widget.paddingLeftRight),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(widget.cardRadius),
        child: PageView.builder(
          controller: _pageController,
          onPageChanged: (index) {
            var itemCallBack = callBack;
            if (index == 0) {
              _resetPageState(length);
            }
            print("[indicator]offset:$_pointOffset");
            if (itemCallBack != null && _pointOffset == 0) {
              print('调用页面回调：${index % length} index:$index');
              itemCallBack(index % length);

            }
            _pointOffset = 0;
            _lastPointOffset = 0;
          },
          itemBuilder: (context, index) {
            return Image.network(
              widget.srcs[index % length],
            );
          },
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    var length = widget.srcs.length;
    return Stack(
      children: <Widget>[
        _buildSwipeBannerContainer(callBack: (index) {
          _resetCurrentIndex(index);
        }),
        Positioned(
          child: Container(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: _buildIndicator(length, _currentPage),
            ),
            height: 15,
            width: 150,
          ),
          right: 15 + widget.paddingLeftRight,
          bottom: widget.paddingTopBottom / 2,
        )
      ],
    );
  }
}
